package wci.frontend.c;

import java.util.HashSet;
import java.util.Hashtable;

import wci.frontend.TokenType;


/**
 * Enum of the C reserved words and special symbols
 * @author Greg Drysdale
 */


public enum CTokenType implements TokenType
{
   // Reserved words
   AUTO, DOUBLE, INT, STRUCT, LONG, BREAK, ELSE, SWITCH, CASE,
   ENUM, REGISTER, TYPEDEF, CHAR, EXTERN, RETURN, UNION,
   CONST, FLOAT, SHORT, UNSIGNED, CONTINUE, FOR, SIGNED,
   VOID, DEFAULT, GOTO, SIZEOF, VOLATILE, DO, IF, STATIC,
   WHILE,
   
   // Special Symbols
   BITWISE_COMPLEMENT("~") /* TILDE */, NOT("!") /* EXCLAMATION */, AT("@") /* valid op? */,
   MODULO("%"), BITWISE_XOR("^") /* CARET/Circumflex */,
   AMPERSAND("&") /* ADDRESS and AND */, ASTERISK("*"), MINUS("-"), PLUS("+"), EQUAL("="),
   BITWISE_OR("|"), DIVIDE("/"), COLON(":"), SEMICOLON(";"), QUESTION_MARK("?"),
   LESS_THAN("<"), GREATER_THAN(">"), PERIOD("."), COMMA(","), SINGLE_QUOTE("'"),
   DOUBLE_QUOTE("\""), LEFT_PARENTHESIS("("), RIGHT_PARENTHESIS(")"), LEFT_BRACKET("["),
   RIGHT_BRACKET("]"), LEFT_BRACE("{"), RIGHT_BRACE("}"), PLUS_PLUS("++"), MINUS_MINUS("--"),
   BITSHIFT_LEFT("<<"), BITSHIFT_RIGHT(">>"), LESS_THAN_EQUALS("<="), GREATER_THAN_EQUALS(">="),
   PLUS_EQUALS("+="), MINUS_EQUALS("-="), TIMES_EQUALS("*=") /* ASTERISK OR STAR EQUALS? */,
   DIVIDE_EQUALS("/="), EQUAL_EQUAL("=="), BITWISE_OR_EQUALS("|="),
   MODULO_EQUALS("%="), BITWISE_AND_EQUALS("&="), BOOLEAN_OR("||"), BOOLEAN_AND("&&"), NOT_EQUALS("!="),
   LINE_COMMENT("//"), BLOCK_COMMENT_OPEN("/*"), BLOCK_COMMENT_CLOSE("*/"), BITSHIFT_LEFT_EQUALS("<<="),
   BITSHIFT_RIGHT_EQUALS(">>="),
   
   IDENTIFIER, INTEGER, REAL, STRING, CHARACTER,
   ERROR, END_OF_FILE;
   
   private static final int FIRST_RESERVED_INDEX = AUTO.ordinal();
   private static final int LAST_RESERVED_INDEX  = WHILE.ordinal();

   private static final int FIRST_SPECIAL_INDEX = BITWISE_COMPLEMENT.ordinal();
   private static final int LAST_SPECIAL_INDEX  = BITSHIFT_RIGHT_EQUALS.ordinal();

   private String text;  // token text

   /**
    * Constructor.
    */
   CTokenType()
   {
       this.text = this.toString().toLowerCase();
   }

   /**
    * Constructor.
    * @param text the token text.
    */
   CTokenType(String text)
   {
       this.text = text;
   }

   /**
    * Getter.
    * @return the token text.
    */
   public String getText()
   {
       return text;
   }

   // Set of lower-cased Pascal reserved word text strings.
   public static HashSet<String> RESERVED_WORDS = new HashSet<String>();
   static {
       CTokenType values[] = CTokenType.values();
       for (int i = FIRST_RESERVED_INDEX; i <= LAST_RESERVED_INDEX; ++i) {
           RESERVED_WORDS.add(values[i].getText().toLowerCase());
       }
   }

   // Hash table of Pascal special symbols.  Each special symbol's text
   // is the key to its Pascal token type.
   public static Hashtable<String, CTokenType> SPECIAL_SYMBOLS =
       new Hashtable<String, CTokenType>();
   static {
       CTokenType values[] = CTokenType.values();
       for (int i = FIRST_SPECIAL_INDEX; i <= LAST_SPECIAL_INDEX; ++i) {
           SPECIAL_SYMBOLS.put(values[i].getText(), values[i]);
       }
   }
   
}